发送邮件
实际项目中可以用多线程发送邮件。
1. 协议
1.1. 接收
POP3:
全称为 Simple Mail Transfer Protocol,简单邮件传输协议。它定义了邮件客户端软件和SMTP邮件服务器之间,以及两台SMTP邮件服务器之间的通信规则。
IMAP:
全称为 Internet Message Access Protocol,Internet消息访问协议,它是对POP3协议的一种扩展,也是定义了邮件客户端软件和IMAP邮件服务器的通信规则。
1.2. 发送
SMTP
全称为 Post Office Protocol,邮局协议。它定义了邮件客户端软件和POP3邮件服务器的通信规则
2. 所需依赖
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
3. 简单邮件的实现
mail.host=smtp.qq.com
mail.transport.protocol=smtp
mail.smtp.auth=true
[email protected]
mail.password=xxxxx
package com.gs.utils;
import com.sun.mail.util.MailSSLSocketFactory;
import org.junit.Test;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Properties;
/**
* @author admin
* @date 2021/9/10 1:54 下午
*/
public class Email {
public void sendEmail(InternetAddress emailAddress, String title, String contents) throws IOException, GeneralSecurityException, MessagingException {
final Properties prop = new Properties();
prop.load(Email.class.getClassLoader().getResourceAsStream("mail.properties"));
// 配置SSL加密
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sf);
// 使用JavaMail发送邮件的5个步骤
// 1、创建定义整个应用程序所需的环境信息的 Session 对象
Session session = Session.getDefaultInstance(prop, new Authenticator() { // 获取和SMTP服务器的连接对象
@Override
public PasswordAuthentication getPasswordAuthentication() {
//发件人邮件用户名、授权码
return new PasswordAuthentication(prop.getProperty("mail.username"), prop.getProperty("mail.password"));
}
});
// 开启Session的debug模式,这样就可以查看到程序发送Email的运行状态
session.setDebug(true);
// 2、通过session得到transport对象
Transport ts = session.getTransport();
// 通过这一次和SMTP服务器的连接对象获取发送邮件的传输对象
// 3、使用邮箱的用户名和授权码连上SMTP邮件服务器,即登陆
ts.connect(prop.getProperty("mail.host"), prop.getProperty("mail.username"), prop.getProperty("mail.password"));
// 4、创建邮件对象MimeMessage——点击网页上的写信
// 创建一个邮件对象
MimeMessage message = new MimeMessage(session);
// 指明邮件的发件人——在网页上填写发件人
message.setFrom(new InternetAddress(prop.getProperty("mail.username"))); // 设置发件人
message.setRecipient(Message.RecipientType.TO, emailAddress); // 设置收件人
// 邮件的标题——在网页上填写邮件标题
message.setSubject(title);// 设置邮件主题
// 邮件的文本内容——在网页上填写邮件内容
message.setContent(contents, "text/html;charset=UTF-8");//设置邮件的具体内容
// 5、发送邮件——在网页上点击发送按钮
ts.sendMessage(message, message.getAllRecipients());
// 6、关闭连接对象,即关闭服务器上的连接资源
ts.close();
}
@Test
public void testSendEmail() {
try {
InternetAddress internetAddress = new InternetAddress("[email protected]");
String title = "简单邮件发送实现";
String content = "<h2 style='color:red'>你好啊!</h2>";
this.sendEmail(internetAddress, title, content);
} catch (IOException | GeneralSecurityException | MessagingException e) {
e.printStackTrace();
}
}
}
4. 复杂邮件的实现
MIME(多用途互联网邮件扩展类型)
MimeBodyPart类
javax.mail.internet.MimeBodyPart类表示的是一个MIME消息,它和MimeMessage类一样都是从Part接口继承过来。即一个MIME消息对应一个MimeBodyPart对象,而MimeBodyPart对象就是我们写的邮件内容中的元素
MimeMultipart类
javax.mail.internet.MimeMultipart是抽象类 Multipart的实现子类,它用来组合多个MIME消息。一个MimeMultipart对象可以包含多个代表MIME消息的MimeBodyPart对象。即一个MimeMultipart对象表示多个MimeBodyPart的集合,而一个MimeMultipart表示的就是我们一封邮件的内容
MimeMultipart对象的使用的时候需要设置setSubType()的属性值,一共就下面3种取值
- alternative:表明这个MimeMultipart对象中的MimeMessage对象的数据是纯文本文件
- related:表明这个MimeMultipart对象中的MimeMessage对象的数据包含非纯文本文件
- mixed:表明这个MimeMultipart对象中的MimeMessage对象的数据包含附件
复杂邮件的实现只需更改上述代码的设置邮件内容本部分
// 准备邮件数据
// 准备图片数据
MimeBodyPart image = new MimeBodyPart(); // 获取一个图片的MimeBodyPart对象
DataHandler dh = new DataHandler(new FileDataSource("图片的地址")); // 由于图片需要字符化才能传输,所以需要获取一个DataHandler对象
image.setDataHandler(dh); // 将图片序列化
image.setContentID("images.jpg"); // 为图片的MimeBodyPart对象设置一个ID,我们在文字中就可以使用它了
// 准备正文数据
MimeBodyPart text = new MimeBodyPart(); // 获取一个文本的MimeBodyPart对象
text.setContent("这是一封邮件正文带图片<img src='cid:images.jpg'>的邮件", "text/html;charset=UTF-8"); // 设置文本内容,注意在里面嵌入了<img src='cid:bz.jpg'>
// 描述数据关系
MimeMultipart mm = new MimeMultipart(); // 获取MimeMultipart
mm.addBodyPart(text); // 将文本MimeBodyPart对象加入MimeMultipart中
mm.addBodyPart(image); // 将图片MimeBodyPart对象加入MimeMultipart中
mm.setSubType("related"); // 设置MimeMultipart对象的相对熟悉为related,即发送的数据为文本+非附件资源
//设置到消息中,保存修改
message.setContent(mm); // 将MimeMultipart放入消息对象中
message.saveChanges(); // 保存上面的修改